﻿using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;

namespace Dapr.Actors.Generators;

/// <summary>
/// Templates for generating source code.
/// </summary>
internal static partial class Templates
{
    /// <summary>
    /// Returns the <see cref="SourceText"/> for the ActorMethodAttribute.
    /// </summary>
    /// <param name="destinationNamespace">Namespace where to generate attribute.</param>
    /// <returns>The <see cref="SourceText"/> representing the ActorMethodAttribute.</returns>
    /// <exception cref="ArgumentNullException">Throws when destinationNamespace is null.</exception>
    public static SourceText ActorMethodAttributeSourceText(string destinationNamespace)
    {
        if (destinationNamespace is null)
        {
            throw new ArgumentNullException(nameof(destinationNamespace));
        }

        var source = $@"
// <auto-generated/>

#nullable enable

using System;

namespace {destinationNamespace}
{{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    internal sealed class {Constants.ActorMethodAttributeTypeName} : Attribute
    {{
        public string? Name {{ get; set; }}
    }}
}}";

        return SourceText.From(
            SyntaxFactory.ParseCompilationUnit(source)
                .NormalizeWhitespace()
                .ToFullString(),
            Encoding.UTF8);
    }

    /// <summary>
    /// Returns the <see cref="SourceText"/> for the GenerateActorClientAttribute.
    /// </summary>
    /// <param name="destinationNamespace">Namespace where to generate attribute.</param>
    /// <returns>The <see cref="SourceText"/> representing the ActorMethodAttribute.</returns>
    /// <exception cref="ArgumentNullException">Throws when destinationNamespace is null.</exception>
    public static SourceText GenerateActorClientAttributeSourceText(string destinationNamespace)
    {
        if (destinationNamespace is null)
        {
            throw new ArgumentNullException(nameof(destinationNamespace));
        }

        string source = $@"
// <auto-generated/>

#nullable enable

using System;

namespace {destinationNamespace}
{{
    [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
    internal sealed class {Constants.GenerateActorClientAttributeTypeName} : Attribute
    {{
        public string? Name {{ get; set; }}

        public string? Namespace {{ get; set; }}
    }}
}}";

        return SourceText.From(
            SyntaxFactory.ParseCompilationUnit(source)
                .NormalizeWhitespace()
                .ToFullString(),
            Encoding.UTF8);
    }
}